package com.task.core.service.impl;

import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Resource;

import com.task.common.constant.ErrorCodeConstants;
import com.task.common.core.redis.RedisCache;
import com.task.common.enums.QuestionOperationTypeEnum;
import com.task.common.enums.QuestionPromptContentEnum;
import com.task.common.info.QuestionShowInfo;
import com.task.common.redis.RedisKeyConstants;
import com.task.common.utils.bean.BeanUtils;
import com.task.core.domain.EngineInfo;
import com.task.core.vo.resp.EngineSchemeDetailRespVo;
import io.jsonwebtoken.lang.Collections;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import com.task.common.annotation.DataScope;
import com.task.common.domain.info.KeyAndValue;
import com.task.common.enums.QuestionInfoTypeEnum;
import com.task.common.exception.ServiceException;
import com.task.common.utils.SecurityUtils;
import com.task.common.utils.uuid.UUID;
import com.task.core.domain.EngineSchemeInfo;
import com.task.core.domain.RelationEngineAndSchemeInfo;
import com.task.core.dto.request.EngineSchemeRequestDTO;
import com.task.core.dto.request.QuestionInfoRequestDTO;
import com.task.core.mapper.EngineSchemeMapper;
import com.task.core.service.EngineSchemeService;
import com.task.core.service.EngineService;
import com.task.core.service.QuestionInfoService;

/**
 * @author 迪迦.
 * @date 2025/1/6 16:47
 */
@Service
public class EngineSchemeServiceImpl implements EngineSchemeService {

  @Resource
  private EngineSchemeMapper engineSchemeMapper;

  @Resource
  private EngineService engineService;

  @Resource
  private QuestionInfoService questionInfoService;

  @Resource
  private RedisCache redisService;

  @Override
  @DataScope(deptAlias = "dept", userAlias = "su")
  public List<EngineSchemeInfo> getEngineSchemeByPage(EngineSchemeRequestDTO request) {
    List<EngineSchemeInfo> engineSchemeByPage = engineSchemeMapper.getEngineSchemeByPage(request);
    for (EngineSchemeInfo info : engineSchemeByPage) {
      List<QuestionShowInfo> questionShowInfoList = questionInfoService.getQuestionInfosByTypeAndCode(QuestionInfoTypeEnum.ENGINE.name(), info.getCode());
      questionShowInfoList.stream().
              forEach(f ->{
                if( QuestionOperationTypeEnum.DELETE.getCode().equals(f.getOperationType()) &&
                        QuestionInfoTypeEnum.ENGINE.name().equals(f.getQuestionType()) ){
                  f.setShowContent(info.getEngineSchemeName()+","+QuestionPromptContentEnum.ENGINE_DELETE_PROMPT_CONTENT.getMsg());
                }else {
                  f.setShowContent(info.getEngineSchemeName()+","+f.getShowContent());
                }
              });
      info.setQuestionInfos(questionShowInfoList);
    }
    return engineSchemeByPage;
  }

  @Override
  public EngineSchemeInfo getEngineSchemeDetail(String code) {
    EngineSchemeInfo engineSchemeDetail = engineSchemeMapper.getEngineSchemeDetail(code);
    if (ObjectUtils.isEmpty(engineSchemeDetail)) {
      throw new ServiceException("数据不存在");
    }
    List<RelationEngineAndSchemeInfo> relationEngineAndSchemeInfos = getRelation(engineSchemeDetail.getCode());

//    //随机获取一个引擎并放入第一条，其他的按照权重排序
//    if (!ObjectUtils.isEmpty(relationEngineAndSchemeInfos)){
//
//      //随机获取一条
//      Random random = new Random();
//      int randomIndex = random.nextInt(relationEngineAndSchemeInfos.size());
//      RelationEngineAndSchemeInfo randomEngineSchemeInfo = relationEngineAndSchemeInfos.get(randomIndex);
//      relationEngineAndSchemeInfos.remove(randomIndex);
//
//      //引擎权重排序
//      Collections.sort(relationEngineAndSchemeInfos, new Comparator<RelationEngineAndSchemeInfo>() {
//          @Override
//          public int compare(RelationEngineAndSchemeInfo o1, RelationEngineAndSchemeInfo o2) {
//              return Integer.compare(o2.getWeight(), o1.getWeight());
//          }
//      });
//
//      //添加到第一条中
//      relationEngineAndSchemeInfos.add(0,randomEngineSchemeInfo);
//
//    }
    if(!ObjectUtils.isEmpty(relationEngineAndSchemeInfos)){
      List<RelationEngineAndSchemeInfo> collect = relationEngineAndSchemeInfos.stream().filter(f -> f.getEngineName()!=null).collect(Collectors.toList());
      engineSchemeDetail.setEngineAndWeights(collect);
    }
    return engineSchemeDetail;
  }

  @Override
  @DataScope(deptAlias = "dept", userAlias = "su")
  public List<KeyAndValue> getEngineSchemeForOption(EngineSchemeRequestDTO request) {
    return engineSchemeMapper.getEngineSchemeForOption(request);
  }

  @Transactional
  @Override
  public void addEngineScheme(EngineSchemeRequestDTO request) {
    if (CollectionUtils.isEmpty(request.getVersionCodes())) {
      throw new ServiceException("版本编号不能为空");
    }
    if (CollectionUtils.isEmpty(request.getEngineAndWeights())) {
      throw new ServiceException("引擎配置不能为空");
    }
    //按前端提交上来的版本编号集合查询数据库,和数据库现有全量数据进行对比,如果数量不同就说明有修改或更新或删除
    if (engineService.getCountByVersionCodes(request.getVersionCodes()) != request.getVersionCodes().size()) {
      throw new ServiceException("关联的上层信息已更新,重新获取数据后再提交");
    }
    request.setCode(UUID.randomUUID().toString().replace("-", ""));
    request.setOperationBy(SecurityUtils.getUserId());
    engineSchemeMapper.addEngineScheme(request);
    if (!CollectionUtils.isEmpty(request.getEngineAndWeights())) {
      engineSchemeMapper.addRelation(request.getCode(), request.getEngineAndWeights());
    }
  }

  @Transactional
  @Override
  public void modifyEngineScheme(EngineSchemeRequestDTO request) {
    if (CollectionUtils.isEmpty(request.getVersionCodes())) {
      throw new ServiceException("版本编号不能为空");
    }
    if (CollectionUtils.isEmpty(request.getEngineAndWeights())) {
      throw new ServiceException("引擎配置不能为空");
    }
    //按前端提交上来的版本编号集合查询数据库,和数据库现有全量数据进行对比,如果数量不同就说明有修改或更新或删除
    if (engineService.getCountByVersionCodes(request.getVersionCodes()) != request.getVersionCodes().size()) {
      throw new ServiceException("关联的上层信息已更新,重新获取数据后再提交");
    }
    request.setOperationBy(SecurityUtils.getUserId());
    Integer integer = engineSchemeMapper.modifyEngineScheme(request);
    if(integer == 0) {
      throw new ServiceException("code不存在");
    }
    //删除关系表数据
    engineSchemeMapper.deleteRelation(request.getCode());
    //添加关系
    if (!CollectionUtils.isEmpty(request.getEngineAndWeights())) {
      engineSchemeMapper.addRelation(request.getCode(), request.getEngineAndWeights());
    }
    //查找是否存在已关联的修改过的上层数据
    List<QuestionShowInfo> questions = questionInfoService.getQuestionInfosByTypeAndCode(QuestionInfoTypeEnum.ENGINE.name(), request.getCode());
    if(!Collections.isEmpty(questions)){
      questions.forEach(f ->{
        String key = RedisKeyConstants.QUESTION_FIX_INFO.formatKey(request.getCode(), f.getCode());
        if(!redisService.hasKey(key)){
          redisService.setCacheObject(key,true);
        }
      });
    }
//    questionInfoService.fixQuestion(new QuestionInfoRequestDTO(QuestionInfoTypeEnum.ENGINE, request.getCode(), request.getOperationBy()));
  }

  @Override
  public void deleteEngineScheme(String engineSchemeCode, Long userId) {
    Integer integer = engineSchemeMapper.deleteEngineScheme(engineSchemeCode, userId);
    //删除关系表数据
    engineSchemeMapper.deleteRelation(engineSchemeCode);
    if(integer == 0) {
      throw new ServiceException("code不存在");
    }
  }

  @Override
  public List<String> getAllCodes() {
    return engineSchemeMapper.getAllCodes();
  }

  @Override
  public List<RelationEngineAndSchemeInfo> getRelation(String code) {
    return engineSchemeMapper.getRelation(code);
  }

  @Override
  public List<String> getAllCodesByEngineCode(String operationCode) {
    return engineSchemeMapper.getAllCodesByEngineCode(operationCode);
  }

  @Override
  public EngineSchemeInfo getEngineSchemeByCode(String dataCode) {
    return engineSchemeMapper.getEngineSchemeByCode(dataCode);
  }

  @Override
  public List<RelationEngineAndSchemeInfo> getEngineAndEngineSchemeRelation(String engineSchemeCode) {
    return engineSchemeMapper.getEngineAndEngineSchemeRelation(engineSchemeCode);
  }

  @Override
  public EngineSchemeDetailRespVo getEngineSchemeDetailByCode(String engineSchemeCode) {
    EngineSchemeRequestDTO engineSchemeRequestDTO = new EngineSchemeRequestDTO();
    engineSchemeRequestDTO.setCode(engineSchemeCode);
    EngineSchemeInfo engineScheme = engineSchemeMapper.getEngineSchemeDetailByCode(engineSchemeRequestDTO);
    if(ObjectUtils.isEmpty(engineScheme)){
      throw new ServiceException(ErrorCodeConstants.ENGINE_SCHEMA_NOT_EXIST.getMsg());
    }
    EngineSchemeDetailRespVo engineSchemeDetailRespVo = new EngineSchemeDetailRespVo();
    BeanUtils.copyProperties(engineScheme,engineSchemeDetailRespVo);
    List<RelationEngineAndSchemeInfo> relation = engineSchemeMapper.getEngineAndEngineSchemeRelation(engineSchemeCode);
    if(!CollectionUtils.isEmpty(relation)){
      List<String> engineCodes = relation.stream().map(RelationEngineAndSchemeInfo::getEngineCode).collect(Collectors.toList());
      List<EngineInfo> engineInfos = engineService.getEngineByCodes(engineCodes);
      engineSchemeDetailRespVo.setEngineInfos(engineInfos);
    }
    return engineSchemeDetailRespVo;
  }
}
